package com.tccdemo;

import com.bosssoft.platform.fasttcc.Tcc;
import com.bosssoft.platform.fasttcc.support.feign.EnableTccFeignSupport;
import com.bosssoft.platform.fasttcc.support.spring.EnableTcc;
import com.jfireframework.baseutil.TRACEID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * Hello world!
 */
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient
@Configuration
@ComponentScan
@EnableTcc
@EnableTccFeignSupport
@EnableFeignClients
public class Client implements Transfer
{
    private static final Logger              logger = LoggerFactory.getLogger(Client.class);
    @Resource
    private              AmountOp            amountOp;
    @Resource
    private              ProviderFeignClient providerFeignClient;
    private static final Logger              LOGGER = LoggerFactory.getLogger(Client.class);

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate()
    {
        return new RestTemplate();
    }

    @Autowired
    private RestTemplate restTemplate;

    public void useRestTemplate()
    {
        ResponseEntity<User> forEntity = restTemplate.getForEntity("http://provider/user", User.class);
        User                 body      = forEntity.getBody();
        System.out.println(body);
    }

    public void testFeign()
    {
        User result = providerFeignClient.user();
        LOGGER.debug("收到响应:{}", result);
    }

    public void test2()
    {
        Account byId = amountOp.findById();
        System.out.println(byId);
    }

    @Transactional
    public void testWithoutTcc()
    {
        amountOp.deac();
        String result = restTemplate.getForObject("http://provider/add", String.class);
        logger.debug("{}", result);
    }

    public static void main(String[] args)
    {
        ConfigurableApplicationContext context = SpringApplication.run(Client.class, args);
        Client                         client  = context.getBean(Client.class);
        client.transfer();
    }

    @Override
    @Transactional
    @Tcc(tccInterface = Transfer.class, cancelClass = CancelTransfer.class, confirmClass = ConfirmTransfer.class)
    public void transfer()
    {
        String traceId = TRACEID.currentTraceId();
        amountOp.deac();
        logger.debug("traceId:{} 本地冻结完成，准备远端调用", traceId);
//        String result = restTemplate.getForObject("http://provider/add", String.class);
        String result = providerFeignClient.add();
        logger.debug("traceId:{} 远端增加完成，结果:{}", traceId, result);
    }
}
